/**
 * 淘宝店铺数据评分劫持(针对店铺详情页)
 * url:https://myseller.taobao.com/home.htm/voc/newTask/serverReport
 * 劫持指定api，并伪造其他参数多次查询获取所有结果
 */

import type { PlasmoCSConfig } from "plasmo"

export const config: PlasmoCSConfig = {
  // 需要注入的网站url
  matches: [
    // 淘宝商家评分
    "https://myseller.taobao.com/home.htm/voc/serverReport"
  ],
  world: "MAIN",
  run_at: "document_start",
  // 注入所有frames
  all_frames: true
}

/**
 * 此为淘宝店铺体验分数据api拦截的注入脚本 (只针对iframe)
 * 由于淘宝使用自家的mtop库进行数据请求，无法直接使用xhr或fetch拦截
 * 所以这里直接改造mtop库的request方法，对请求进行拦截
 * *针对店铺评分的api逆向分析结果构建，专用模块
 */

// 二级数据查询索引， api： mtop.sdx.index.page.pageinit
const l2_mainIndexCode = [
  // 宝贝质量
  "newGoods",
  // 物流速度
  "newLogistics",
  // 服务保障
  "newServices"
]

const sendResultMessage = (res: any) => {
  const { api, data } = res
  // 当前目标
  let target: any = window
  // 判断当前是否为iframe
  if (window.self !== window.top) {
    // 当前为iframe中
    target = window.parent
  }
  // 消息传递
  target.dispatchEvent(
    new CustomEvent("hijackTbEvent", {
      detail: { api: api, data: data }
    })
  )
}

// 使用 Proxy 监控 window.lib 的赋值情况
const libProxyHandler = {
  set: function (target: any, key: string, value: any) {
    if (key === "mtop") {
      // // 使用 Proxy 监控 window.lib.mtop 的赋值情况
      value = new Proxy(value, {
        set: function (mtopTarget, mtopKey, mtopValue) {
          // 只对request进行劫持, 且当前为iframe目标时处理
          if (
            ["request"].includes(String(mtopKey)) &&
            window.self !== window.top
          ) {
            const originRequest = mtopValue
            mtopTarget[mtopKey] = async function (
              params: any,
              successCallback: Function,
              failureCallback: Function
            ) {
              // 直接获取原始结果
              // 如果successCallBack，无法劫持，直接调用
              const res = await originRequest.call(
                this,
                params,
                successCallback,
                failureCallback
              )
              // console.log(`${mainIndexCode}-拦截改造
              if (res) {
                // 结果信息传递
                sendResultMessage(res)
              }
              // 如果api=mtop.sdx.nps.home.benefits
              // 查询结构与 mtop.sdx.index.page.indexDetail 相同
              // 直接改造重复查询结果
              if (params["api"] === "mtop.sdx.nps.home.benefits") {
                // 改造参数
                const reforgeParams = { ...params }
                // 从结果中获取查询日期
                const queryUpdateDate = res?.data?.data?.updateDate
                // 改造api
                reforgeParams["api"] = "mtop.sdx.index.page.pageinit"
                // 遍历目标查询
                for (const mainIndexCode of l2_mainIndexCode) {
                  // 改造data
                  reforgeParams["data"] = {
                    mainIndexCode,
                    updateDate: queryUpdateDate
                  }
                  // 重复请求
                  const reforgeRes = await originRequest.call(
                    this,
                    reforgeParams,
                    successCallback,
                    failureCallback
                  )
                  // 打印测试结果
                  // console.log(`${mainIndexCode}-拦截改造结果`, reforgeRes)
                  // 结果信息传递
                  sendResultMessage(reforgeRes)
                }
              }
              return res
            }
          } else {
            mtopTarget[mtopKey] = mtopValue
          }
          return true
        }
      })
    }
    target[key] = value
    return true
  }
}

// 代理 window.lib 对象
window["lib"] = new Proxy(window["lib"] || {}, libProxyHandler)
